home *** CD-ROM | disk | FTP | other *** search
/ GFX Sensations 1 / Graphic Sensations - Volume 1.iso / tools / amiga / gfx_card / rblanke2.lha / RBlankers / rspliner.c < prev    next >
Encoding:
C/C++ Source or Header  |  1994-07-13  |  20.7 KB  |  746 lines

  1. /*
  2.  * RSpliner
  3.  *
  4.  * A screen blanker for the Retina graphics card.
  5.  * By Michael Heinz, 30 March, 1994
  6.  *
  7.  * This software is FREEWARE.  It may be freely distributed for non-commercial use.        
  8.  * All rights are reserved by the author.              
  9.  *
  10.  */
  11.  
  12. #include <exec/memory.h>
  13. #include <exec/ports.h>
  14. #include <exec/execbase.h>
  15. #include <graphics/displayinfo.h>
  16. #include <intuition/intuitionbase.h>
  17. #include <intuition/gadgetclass.h>
  18. #include <libraries/commodities.h>
  19. #include <libraries/gadtools.h>
  20. #include <dos/dosextens.h>
  21. #include <dos/dostags.h>
  22. #include <utility/tagitem.h>
  23.  
  24. #include <clib/alib_protos.h>
  25. #include <clib/commodities_protos.h>
  26. #include <clib/dos_protos.h>
  27. #include <clib/exec_protos.h>
  28. #include <clib/gadtools_protos.h>
  29. #include <clib/graphics_protos.h>
  30. #include <clib/intuition_protos.h>
  31. #include <clib/macros.h>
  32. #include <clib/retina_protos.h>
  33. #include <libraries/retina.h>
  34.  
  35. #include <string.h>
  36. #include <stdlib.h>
  37.  
  38. #include <pragmas/commodities_pragmas.h>
  39. #include <pragmas/dos_pragmas.h>
  40. #include <pragmas/exec_pragmas.h>
  41. #include <pragmas/gadtools_pragmas.h>
  42. #include <pragmas/graphics_pragmas.h>
  43. #include <pragmas/intuition_pragmas.h>
  44. #include <pragmas/retina_pragmas.h>
  45. #include "blanker.h"
  46.  
  47. UBYTE *VersionString = "$VER: $Id: rspliner.c 2.4 1994/07/12 17:13:22 mheinz Exp mheinz $";
  48.  
  49. unsigned char color_table[] =
  50. {
  51.     0, 0, 0, 0, 0, 70, 0, 0, 76, 0, 0, 82, 0, 0, 88, 0, 0, 94,
  52.     0, 0, 100, 0, 0, 106, 0, 0, 112, 0, 0, 118, 0, 0, 124, 0, 0, 130,
  53.     0, 0, 136, 0, 0, 142, 0, 0, 148, 0, 0, 154, 0, 0, 160, 0, 0, 166,
  54.     0, 0, 172, 0, 0, 178, 0, 0, 184, 0, 0, 190, 0, 0, 196, 0, 0, 202,
  55.     0, 0, 208, 0, 0, 214, 0, 0, 220, 0, 0, 226, 0, 0, 232, 0, 0, 238,
  56.     0, 0, 244, 0, 0, 250, 0, 0, 255, 4, 0, 255, 8, 0, 255, 12, 0, 255,
  57. 16, 0, 255, 20, 0, 255, 24, 0, 255, 28, 0, 255, 32, 0, 255, 36, 0, 255,
  58. 40, 0, 255, 44, 0, 255, 48, 0, 255, 52, 0, 255, 56, 0, 255, 60, 0, 255,
  59. 64, 0, 255, 68, 0, 255, 72, 0, 255, 76, 0, 255, 80, 0, 255, 84, 0, 255,
  60.     88, 0, 255, 92, 0, 255, 96, 0, 255, 100, 0, 255, 104, 0, 255, 108, 0, 255,
  61.     112, 0, 255, 116, 0, 255, 120, 0, 255, 124, 0, 255, 128, 0, 255, 132, 0, 255,
  62.     136, 0, 255, 140, 0, 255, 144, 0, 255, 148, 0, 255, 152, 0, 255, 156, 0, 255,
  63.     160, 0, 255, 164, 0, 255, 168, 0, 255, 172, 0, 255, 176, 0, 255, 180, 0, 255,
  64.     184, 0, 255, 188, 0, 255, 192, 0, 255, 196, 0, 255, 200, 0, 255, 204, 0, 255,
  65.     208, 0, 255, 212, 0, 255, 216, 0, 255, 220, 0, 255, 224, 0, 255, 228, 0, 255,
  66.     232, 0, 255, 236, 0, 255, 240, 0, 255, 244, 0, 255, 248, 0, 255, 252, 0, 255,
  67.     255, 0, 252, 255, 0, 248, 255, 0, 244, 255, 0, 240, 255, 0, 236, 255, 0, 232,
  68.     255, 0, 228, 255, 0, 224, 255, 0, 220, 255, 0, 216, 255, 0, 212, 255, 0, 208,
  69.     255, 0, 204, 255, 0, 200, 255, 0, 196, 255, 0, 192, 255, 0, 188, 255, 0, 184,
  70.     255, 0, 180, 255, 0, 176, 255, 0, 172, 255, 0, 168, 255, 0, 164, 255, 0, 160,
  71.     255, 0, 156, 255, 0, 152, 255, 0, 148, 255, 0, 144, 255, 0, 140, 255, 0, 136,
  72.     255, 0, 132, 255, 0, 128, 255, 0, 124, 255, 0, 120, 255, 0, 116, 255, 0, 112,
  73.     255, 0, 108, 255, 0, 104, 255, 0, 100, 255, 0, 96, 255, 0, 92, 255, 0, 88,
  74.     255, 0, 84, 255, 0, 80, 255, 0, 76, 255, 0, 72, 255, 0, 68, 255, 0, 64, 255, 0, 60,
  75.     255, 0, 56, 255, 0, 52, 255, 0, 48, 255, 0, 44, 255, 0, 40, 255, 0, 36, 255, 0, 32,
  76.     255, 0, 28, 255, 0, 24, 255, 0, 20, 255, 0, 16, 255, 0, 12, 255, 0, 8, 255, 0, 4,
  77.     255, 0, 0, 255, 4, 0, 255, 8, 0, 255, 12, 0, 255, 16, 0, 255, 20, 0, 255, 24, 0,
  78.     255, 28, 0, 255, 32, 0, 255, 36, 0, 255, 40, 0, 255, 44, 0, 255, 48, 0, 255, 52, 0,
  79. 255, 56, 0, 255, 60, 0, 255, 64, 0, 255, 68, 0, 255, 72, 0, 255, 76, 0,
  80.     255, 80, 0, 255, 84, 0, 255, 88, 0, 255, 92, 0, 255, 96, 0, 255, 100, 0,
  81.     255, 104, 0, 255, 108, 0, 255, 112, 0, 255, 116, 0, 255, 120, 0, 255, 124, 0,
  82.     255, 128, 0, 255, 132, 0, 255, 136, 0, 255, 140, 0, 255, 144, 0, 255, 148, 0,
  83.     255, 152, 0, 255, 156, 0, 255, 160, 0, 255, 164, 0, 255, 168, 0, 255, 172, 0, 255, 176, 0,
  84.     255, 180, 0, 255, 184, 0, 255, 188, 0, 255, 192, 0, 255, 196, 0, 255, 200, 0,
  85.     255, 204, 0, 255, 208, 0, 255, 212, 0, 255, 216, 0, 255, 220, 0, 255, 224, 0,
  86.     255, 228, 0, 255, 232, 0, 255, 236, 0, 255, 240, 0, 255, 244, 0, 255, 248, 0,
  87.     255, 252, 0, 255, 255, 0, 255, 255, 8, 255, 255, 16, 255, 255, 24, 255, 255, 32,
  88.     255, 255, 40, 255, 255, 48, 255, 255, 56, 255, 255, 64, 255, 255, 72, 255, 255, 80,
  89.     255, 255, 88, 255, 255, 96, 255, 255, 104, 255, 255, 112, 255, 255, 120, 255, 255, 128,
  90.     255, 255, 136, 255, 255, 144, 255, 255, 152, 255, 255, 160, 255, 255, 168, 255, 255, 176,
  91.     255, 255, 184, 255, 255, 192, 255, 255, 200, 255, 255, 208, 255, 255, 216, 255, 255, 224,
  92.     255, 255, 232, 255, 255, 240, 255, 255, 248, 255, 255, 255,
  93. };
  94.  
  95. /*
  96.  * A handy request structure for reporting that we've up and died.
  97.  */
  98. struct EasyStruct quitreq =
  99. {
  100.     sizeof(struct EasyStruct),
  101.     0,
  102.     "RSpliner",
  103.     "RSpliner has suffered an untimely demise\ndue to: %s",
  104.     "OK|OK"
  105. };
  106.  
  107. /*
  108.  * Definitions for our Commodity
  109.  */
  110. struct NewBroker NewBroker =
  111. {NB_VERSION, "RSpliner ", NULL,
  112.  "Silly Rabbit, Qix are for Qids!", NBU_NOTIFY | NBU_UNIQUE, COF_SHOW_HIDE,
  113.  0, NULL, 0};
  114.  
  115.  
  116. #define MAX_SPEED     20L
  117. #define MAX_LINES     300L
  118. #define LINE_BUF      512L
  119.  
  120. #define MIN_LINES      10L
  121. #define DEF_LINES     100L
  122. #define DEF_SPEED     10L
  123.  
  124. #define DELTA_V          10L
  125.  
  126. LONG NumLines, Speed;
  127.  
  128. typedef struct {
  129.     unsigned char color;
  130.     int cur_point;
  131.     int last_point;
  132.     int max_points;
  133.     int tic, speed;
  134.     int xv1, yv1, xv2, yv2;
  135.     int point_list[LINE_BUF][4];
  136. } PList;
  137.  
  138. PList plist;
  139.  
  140. /*
  141.  * Definitions for our configuration window
  142.  */
  143.  
  144. struct NewWindow NewBlankerWindow =
  145. {
  146.     80, 16, 0, 0, 0, 1,
  147.     IDCMP_CLOSEWINDOW | IDCMP_REFRESHWINDOW | IDCMP_GADGETDOWN |
  148.     IDCMP_GADGETUP | IDCMP_VANILLAKEY | SLIDERIDCMP | LISTVIEWIDCMP,
  149.     WINDOWCLOSE | WINDOWDRAG | WINDOWDEPTH | SIMPLE_REFRESH,
  150.     NULL, NULL, NULL, NULL, NULL, 0, 0, 0, 0,
  151.     WBENCHSCREEN
  152. };
  153.  
  154. struct Window *BlankerWindow;
  155.  
  156. #define GID_HIDE          1
  157. #define GID_BLANK         2
  158. #define GID_QUIT          3
  159. #define GID_TIMEOUT       4
  160. #define GID_CLIENT        5
  161. #define GID_LINES          6
  162. #define GID_SPEED         7
  163.  
  164. #define NUM_GADS         7
  165.  
  166. struct VisualInfo *BlankerVisualInfo;
  167. struct Gadget *BlankerGadgets;
  168. struct TextAttr BlankerAttr =
  169. {"topaz.font", TOPAZ_EIGHTY, FS_NORMAL, FPF_ROMFONT};
  170.  
  171. struct NewGadget NewBlankerGadgets[NUM_GADS] =
  172. {16, 101, 48, 12, "_Hide", &BlankerAttr, GID_HIDE, PLACETEXT_IN, NULL, NULL,
  173.  80, 101, 48, 12, "_Blank", &BlankerAttr, GID_BLANK, PLACETEXT_IN, NULL, NULL,
  174.  144, 101, 48, 12, "_Quit", &BlankerAttr, GID_QUIT, PLACETEXT_IN, NULL, NULL,
  175.  136, 5, 66, 12, "Timeout", &BlankerAttr, GID_TIMEOUT, PLACETEXT_LEFT, NULL, NULL,
  176.  136, 21, 66, 12, "Client Timeout", &BlankerAttr, GID_CLIENT, PLACETEXT_LEFT, NULL, NULL,
  177.  136, 53, 66, 12, "Speed    ", &BlankerAttr, GID_SPEED, PLACETEXT_LEFT, NULL, NULL,
  178.  136, 69, 66, 12, "Lines    ", &BlankerAttr, GID_LINES, PLACETEXT_LEFT, NULL, NULL,
  179. };
  180.  
  181. UBYTE BlankerGadgetKinds[NUM_GADS] =
  182. {
  183.     BUTTON_KIND, BUTTON_KIND, BUTTON_KIND, INTEGER_KIND, INTEGER_KIND, SLIDER_KIND,
  184.     SLIDER_KIND,
  185. };
  186.  
  187. struct TagItem ButtonGadgetTags[] =
  188. {GT_Underscore, (ULONG) '_', TAG_DONE, 0L};
  189.  
  190. struct TagItem TimeGadgetTags[] =
  191. {GTIN_Number, 0L, GTIN_MaxChars, 4L, TAG_DONE, 0L};
  192.  
  193. struct TagItem ClientGadgetTags[] =
  194. {GTIN_Number, 0L, GTIN_MaxChars, 2L, TAG_DONE, 0L};
  195.  
  196. struct TagItem SpeedGadgetTags[] =
  197. {GTSL_Level, 0L, GTSL_Min, 1L, GTSL_Max, MAX_SPEED, GTSL_LevelFormat, 0L,
  198.  GTSL_LevelPlace, PLACETEXT_LEFT, GTSL_MaxLevelLen, 2L, GA_RELVERIFY, TRUE,
  199.  TAG_DONE, 0L};
  200.  
  201. struct TagItem LinesGadgetTags[] =
  202. {GTSL_Level, 0L, GTSL_Min, MIN_LINES, GTSL_Max, MAX_LINES, GTSL_LevelFormat, 0L,
  203.  GTSL_LevelPlace, PLACETEXT_LEFT, GTSL_MaxLevelLen, 3L, GA_RELVERIFY, TRUE,
  204.  TAG_DONE, 0L};
  205.  
  206. struct TagItem *BlankerGadgetTagLists[NUM_GADS] =
  207. {
  208.     &ButtonGadgetTags[0],
  209.     &ButtonGadgetTags[0],
  210.     &ButtonGadgetTags[0],
  211.     &TimeGadgetTags[0],
  212.     &ClientGadgetTags[0],
  213.     &SpeedGadgetTags[0],
  214.     &LinesGadgetTags[0],
  215. };
  216.  
  217. void
  218. CloseBlankerWindow(void)
  219. {
  220.     if (BlankerWindow) {
  221.         /*
  222.          * We save the current position of the window
  223.          * so it will re-open in the same place, later.
  224.          */
  225.         NewBlankerWindow.LeftEdge = BlankerWindow->LeftEdge;
  226.         NewBlankerWindow.TopEdge = BlankerWindow->TopEdge;
  227.  
  228.         RemTool(BlankerGadgets);
  229.         RemTool(BlankerVisualInfo);
  230.         RemTool(BlankerWindow);
  231.         BlankerWindow = NULL;
  232.     }
  233. }
  234.  
  235. void
  236. OpenBlankerWindow(void)
  237. {
  238.     struct Gadget *Ptr;
  239.     UWORD Index;
  240.     static char Title[80];
  241.  
  242.     if (BlankerWindow == NULL) {
  243.         strcpy(Title, "RSpliner = <");
  244.         strcat(Title, PopKey);
  245.         strcat(Title, ">");
  246.  
  247.         if (BlankerWindow = OpenWindowTags(&NewBlankerWindow, WA_Title, Title,
  248.                                    WA_AutoAdjust, TRUE, WA_InnerWidth,
  249.                                 212, WA_InnerHeight, 118, TAG_DONE)) {
  250.  
  251.             AddTool(BlankerWindow, CloseWindow, NULL, "Could not open the window.");
  252.  
  253.             if ((BlankerVisualInfo = GetVisualInfo(BlankerWindow->WScreen, TAG_DONE))
  254.                 == NULL) {
  255.                 RemTool(BlankerWindow);
  256.                 return;
  257.             }
  258.             AddTool(BlankerVisualInfo, FreeVisualInfo, 0L,
  259.                     "Couldn't get visual data.");
  260.  
  261.             BlankerGadgets = NULL;
  262.             if ((Ptr = CreateContext(&BlankerGadgets)) == NULL) {
  263.                 RemTool(BlankerVisualInfo);
  264.                 RemTool(BlankerWindow);
  265.                 return;
  266.             }
  267.             AddTool(Ptr, FreeGadgets, 0L, "Couldn't allocate the gadgets.");
  268.  
  269.             /*
  270.              * Here we re-load the gadgets with the current settings. 
  271.              */
  272.             TimeGadgetTags[0].ti_Data = (ULONG) TimeOut;
  273.             ClientGadgetTags[0].ti_Data = (ULONG) ClientTimeOut;
  274.             SpeedGadgetTags[0].ti_Data = (ULONG) Speed;
  275.             SpeedGadgetTags[3].ti_Data = (ULONG) "%2ld";
  276.             LinesGadgetTags[0].ti_Data = (ULONG) NumLines;
  277.             LinesGadgetTags[3].ti_Data = (ULONG) "%3ld";
  278.  
  279.             for (Index = 0L; Index < NUM_GADS; Index++) {
  280.                 NewBlankerGadgets[Index].ng_TopEdge += BlankerWindow->BorderTop;
  281.  
  282.                 NewBlankerGadgets[Index].ng_VisualInfo = BlankerVisualInfo;
  283.                 Ptr = CreateGadgetA((ULONG) BlankerGadgetKinds[Index], Ptr,
  284.                                     &NewBlankerGadgets[Index],
  285.                                     BlankerGadgetTagLists[Index]);
  286.                 if (Ptr == NULL) {
  287.                     CloseBlankerWindow();
  288.                     return;
  289.                 }
  290.                 NewBlankerGadgets[Index].ng_TopEdge -= BlankerWindow->BorderTop;
  291.             }
  292.  
  293.             AddGList(BlankerWindow, BlankerGadgets, 0L, -1L, NULL);
  294.             RefreshGadgets(BlankerGadgets, BlankerWindow, NULL);
  295.             GT_RefreshWindow(BlankerWindow, NULL);
  296.         }
  297.     }
  298.     ScreenToFront(BlankerWindow->WScreen);
  299.     WindowToFront(BlankerWindow);
  300.     ActivateWindow(BlankerWindow);
  301. }
  302.  
  303. WORD __inline
  304. Insure1(WORD val)
  305. {
  306.     return (WORD)((val == 0) ? (WORD)1 : val);
  307. }
  308.  
  309. /*
  310.  * Create the list of points.
  311.  */
  312. void *__regargs
  313. CreateLines(struct RetinaScreen * Screen,
  314.             LONG NumLines, LONG Speed)
  315. {
  316.     int i;
  317.  
  318.     if (!Screen)
  319.         return NULL;
  320.  
  321.     for (i = 0; i < LINE_BUF; i++) {
  322.         plist.point_list[i][0] = -1;
  323.         plist.point_list[i][1] = -1;
  324.         plist.point_list[i][2] = -1;
  325.         plist.point_list[i][3] = -1;
  326.     }
  327.  
  328.     plist.color = 1;
  329.     plist.max_points = NumLines;
  330.     plist.speed = Speed;
  331.     plist.last_point = 0;
  332.     plist.cur_point = NumLines;
  333.     plist.point_list[NumLines][0] = Random(Screen->rs_Width);
  334.     plist.point_list[NumLines][1] = Random(Screen->rs_Height);
  335.     plist.point_list[NumLines][2] = Random(Screen->rs_Width);
  336.     plist.point_list[NumLines][3] = Random(Screen->rs_Height);
  337.     plist.xv1 = Insure1(RAND(DELTA_V));
  338.     plist.yv1 = Insure1(RAND(DELTA_V));
  339.     plist.xv2 = Insure1(RAND(DELTA_V));
  340.     plist.yv2 = Insure1(RAND(DELTA_V));
  341.  
  342.     return (void *)&plist;
  343. }
  344.  
  345. int __inline __regargs
  346. Bound(int l, int *m, int u)
  347. {
  348.     if (*m < l) {
  349.         *m = l;
  350.         return 1;
  351.     }
  352.     if (*m >= u) {
  353.         *m = u - 1;
  354.         return 1;
  355.     }
  356.     return 0;
  357. }
  358.  
  359. /*
  360.  * move the Lines and redraw them 
  361.  */
  362. void __regargs
  363. DrawLines(void *xplist, struct RetinaScreen *rs)
  364. {
  365.     int *pl;
  366.     PList *plist=xplist;
  367.  
  368.     /*
  369.      * If we don't have a screen, don't draw on it! (duh.) 
  370.      */
  371.     if (!rs)
  372.         return;
  373.  
  374.     if (plist->tic) {
  375.         plist->tic--;
  376.         return;
  377.     }
  378.     plist->tic = Insure1(MAX_SPEED - plist->speed);
  379.  
  380.     pl = plist->point_list[plist->cur_point];
  381.  
  382.     Retina_SetAPen(rs, plist->color);
  383.     plist->color++;
  384.     Retina_Line(rs, pl[0], pl[1], pl[2], pl[3]);
  385.  
  386.     plist->cur_point = (plist->cur_point + 1) % LINE_BUF;
  387.  
  388.     plist->point_list[plist->cur_point][0] = pl[0] + plist->xv1;
  389.     plist->point_list[plist->cur_point][1] = pl[1] + plist->yv1;
  390.     plist->point_list[plist->cur_point][2] = pl[2] + plist->xv2;
  391.     plist->point_list[plist->cur_point][3] = pl[3] + plist->yv2;
  392.  
  393.     if (Bound(0, &plist->point_list[plist->cur_point][0], rs->rs_Width)) {
  394.         if (plist->xv1 > 0) {
  395.             plist->xv1 = -Insure1(Random(DELTA_V));
  396.         } else {
  397.             plist->xv1 = Insure1(Random(DELTA_V));
  398.         }
  399.     }
  400.     if (Bound(0, &plist->point_list[plist->cur_point][1], rs->rs_Height)) {
  401.         if (plist->yv1 > 0) {
  402.             plist->yv1 = -Insure1(Random(DELTA_V));
  403.         } else {
  404.             plist->yv1 = Insure1(Random(DELTA_V));
  405.         }
  406.     }
  407.     if (Bound(0, &plist->point_list[plist->cur_point][2], rs->rs_Width)) {
  408.         if (plist->xv2 > 0) {
  409.             plist->xv2 = -Insure1(Random(DELTA_V));
  410.         } else {
  411.             plist->xv2 = Insure1(Random(DELTA_V));
  412.         }
  413.     }
  414.     if (Bound(0, &plist->point_list[plist->cur_point][3], rs->rs_Height)) {
  415.         if (plist->yv2 > 0) {
  416.             plist->yv2 = -Insure1(Random(DELTA_V));
  417.         } else {
  418.             plist->yv2 = Insure1(Random(DELTA_V));
  419.         }
  420.     }
  421.     Retina_SetAPen(rs, 0);
  422.     pl = plist->point_list[plist->last_point];
  423.     if (pl[0] >= 0)
  424.         Retina_Line(rs, pl[0], pl[1], pl[2], pl[3]);
  425.  
  426.     plist->last_point = (plist->last_point + 1) % LINE_BUF;
  427.  
  428. }
  429.  
  430. void
  431. main(LONG argc, UBYTE * argv[])
  432. {
  433.     char **ToolTypes;
  434.     CxObj *Broker, *ObjectList, *Filter;
  435.     struct IntuiMessage *IntMsg;
  436.     CxMsg *BlankerCxMsg;
  437.     LONG ThisTimeOut, TimeUntilBlank, TimeUntilBlack;
  438.     struct RetinaScreen *BlankerScreen = NULL;
  439.     struct MsgPort *ClientPort = NULL;
  440.     int BlankFlag = 0;
  441.     LONG BrokerError;
  442.  
  443.     /*
  444.      * open our Libraries 
  445.      */
  446.     AddTool(IntuitionBase = (struct IntuitionBase *)OpenLibrary("intuition.library",
  447.                                                37L), CloseLibrary, 0L,
  448.             "Couldn't open the intuition.library.");
  449.     AddTool(IconBase = OpenLibrary("icon.library", 37L), CloseLibrary, 0L,
  450.             "Couldn't open the icon library.");
  451.     AddTool(CxBase = OpenLibrary("commodities.library", 37L), CloseLibrary, 0L,
  452.             "Couldn't open the commoidities library.");
  453.     AddTool(GadToolsBase = OpenLibrary("gadtools.library", 37L), CloseLibrary, 0L,
  454.             "Couldn't open the gadtools library.");
  455.     AddTool(RetinaBase = (struct RetinaBase *)OpenLibrary("retina.library", 8L),
  456.             CloseLibrary, 0L, "Couldn't open the Retina library.");
  457.  
  458.     /*
  459.      * get our Arguments 
  460.      */
  461.  
  462.     if (ToolTypes = ArgArrayInit(argc, argv))
  463.         AddTool(ToolTypes, ArgArrayDone, 0L, NULL);
  464.  
  465.     /*
  466.      * get some Signals 
  467.      */
  468.  
  469.     ServerProcess = SysBase->ThisTask;
  470.     if ((bsp_TimerSig = AllocSignal(-1L)) == -1)
  471.         Quit(10, "Could not allocate a signal.");
  472.     AddTool((void *)bsp_TimerSig, FreeSignal, 0L, NULL);
  473.     if ((bsp_InputSig = AllocSignal(-1L)) == -1)
  474.         Quit(10, "Could not allocate a signal.");
  475.     AddTool((void *)bsp_InputSig, FreeSignal, 0L, NULL);
  476.     if ((bsp_ClientSig = AllocSignal(-1L)) == -1)
  477.         Quit(10, "Could not allocate a signal.");
  478.     AddTool((void *)bsp_ClientSig, FreeSignal, 0L, NULL);
  479.  
  480.     /*
  481.      * initialize our Broker = install us as a Commodity 
  482.      */
  483.  
  484.     AddTool(CxPort = CreateMsgPort(), DeleteMsgPortSafely, 0L,
  485.             "Failed to create a port.");
  486.  
  487.     /* We hack the version string a little, because it's automatically generated
  488.      * by RCS and we have to shorten it.
  489.      */
  490.     VersionString[36]='\0';
  491.     NewBroker.nb_Title = &VersionString[11];
  492.     NewBroker.nb_Pri = ArgInt(ToolTypes, "CX_PRIORITY", DEF_CX_PRI);
  493.     NewBroker.nb_Port = CxPort;
  494.     Broker = CxBroker(&NewBroker, &BrokerError);
  495.     AddTool(Broker,DeleteCxObjAll, 0L, NULL);
  496.  
  497.     /*
  498.      * get Time Out, Client Time Out and Display mode 
  499.      */
  500.  
  501.     TimeOut = ArgIntRange(ToolTypes, "TIMEOUT", 1L, DEF_TIMEOUT, MAX_TIMEOUT);
  502.     ClientTimeOut = ArgIntRange(ToolTypes, "CLIENTTIMEOUT", 1L, DEF_CLIENT_TIMEOUT,
  503.                               MAX_CLIENT_TIMEOUT);
  504.  
  505.     /*
  506.      * get Parameters for Line Movement 
  507.      */
  508.  
  509.     NumLines = ArgIntRange(ToolTypes, "LINES", MIN_LINES, DEF_LINES, MAX_LINES);
  510.     Speed = ArgIntRange(ToolTypes, "SPEED", 1L, DEF_SPEED, MAX_SPEED);
  511.  
  512.     /*
  513.      * install our hot keys 
  514.      */
  515.  
  516.     PopKey = ArgString(ToolTypes, "CX_POPKEY", DEF_POPKEY);
  517.     BlankKey = ArgString(ToolTypes, "BLANKKEY", DEF_BLANKKEY);
  518.  
  519.     if ((Filter = HotKey(PopKey, CxPort, HOTKEY_OPEN_WINDOW)) == NULL)
  520.         Quit(10, "The CX_POPKEY tool type is invalid.");
  521.     else
  522.         AttachCxObj(Broker, Filter);
  523.     if (CxObjError(Filter))
  524.         Quit(10, "Could not link to the commodity list.");
  525.  
  526.     if ((Filter = HotKey(BlankKey, CxPort, HOTKEY_BLANK_SCREEN)) == NULL)
  527.         Quit(10, "The BLANKKEY tool type is invalid.");
  528.     else
  529.         AttachCxObj(Broker, Filter);
  530.     if (CxObjError(Filter))
  531.         Quit(10, "Could not link to the commodity list.");
  532.  
  533.     /*
  534.      * install our "InputHandler" 
  535.      */
  536.  
  537.     ObjectList = CxCustom(BlankerAction, 0L);
  538.     AttachCxObj(Broker, ObjectList);
  539.     if (CxObjError(ObjectList))
  540.         Quit(10, "Could not link to the commodity list.");
  541.  
  542.     (void)ActivateCxObj(Broker, TRUE);
  543.     AddTool(Broker, ActivateCxObj, 0L, "The broker broke.");
  544.  
  545.     /*
  546.      * open Window on startup if not forbidden 
  547.      */
  548.  
  549.     if (stricmp(ArgString(ToolTypes, "CX_POPUP", ""), "NO"))
  550.         OpenBlankerWindow();
  551.  
  552.     /*
  553.      * increase our Priority 
  554.      */
  555.  
  556.     AddTool(FindTask(NULL), SetTaskPri, (LONG) SetTaskPri(FindTask(NULL), SERVER_PRI),
  557.             "Findtask failed!");
  558.  
  559.     /*
  560.      * start the Loop 
  561.      */
  562.  
  563.     TimeUntilBlank = ThisTimeOut = 10L * TimeOut;
  564.     TimeUntilBlack = 10L * ClientTimeOut;
  565.  
  566.     FOREVER
  567.     {
  568.         ULONG Mask;
  569.  
  570.         if (BlankerWindow)
  571.             Mask = Wait(MASK(bsp_TimerSig) | MASK(bsp_InputSig) | MASK(bsp_ClientSig) |
  572.                         MASK(CxPort->mp_SigBit) |
  573.                         MASK(BlankerWindow->UserPort->mp_SigBit) |
  574.                         SIGBREAKF_CTRL_C);
  575.         else
  576.             Mask = Wait(MASK(bsp_TimerSig) | MASK(bsp_InputSig) | MASK(bsp_ClientSig) |
  577.                         MASK(CxPort->mp_SigBit) | SIGBREAKF_CTRL_C);
  578.  
  579.         /*
  580.          * process Window Events 
  581.          */
  582.  
  583.         while ((BlankerWindow != NULL) && (IntMsg =
  584.                                  GT_GetIMsg(BlankerWindow->UserPort)))
  585.             switch (IntMsg->Class) {
  586.                 struct Gadget *Clicked;
  587.                 UWORD Code;
  588.  
  589.             case IDCMP_CLOSEWINDOW:
  590.                 GT_ReplyIMsg(IntMsg);
  591.                 CloseBlankerWindow();
  592.                 break;
  593.             case IDCMP_REFRESHWINDOW:
  594.                 GT_BeginRefresh(BlankerWindow);
  595.                 GT_EndRefresh(BlankerWindow, TRUE);
  596.                 break;
  597.             case IDCMP_GADGETUP:
  598.                 Code = IntMsg->Code;
  599.                 Clicked = (struct Gadget *)IntMsg->IAddress;
  600.                 GT_ReplyIMsg(IntMsg);
  601.                 switch (Clicked->GadgetID) {
  602.                 case GID_HIDE:
  603.                     CloseBlankerWindow();
  604.                     break;
  605.                 case GID_QUIT:
  606.                     Quit(0, "Normal Termination.");
  607.                 case GID_BLANK:
  608.                     if (TimeUntilBlank)
  609.                         TimeUntilBlank = ThisTimeOut = 2L;
  610.                     break;
  611.                 case GID_TIMEOUT:
  612.                     if (GetNum(BlankerWindow, Clicked, 1L, &TimeOut, MAX_TIMEOUT))
  613.                         TimeUntilBlank = ThisTimeOut = 10L * TimeOut;
  614.                     break;
  615.                 case GID_CLIENT:
  616.                     if (GetNum(BlankerWindow, Clicked, 1L, &ClientTimeOut, MAX_CLIENT_TIMEOUT))
  617.                         TimeUntilBlack = 10L * ClientTimeOut;
  618.                     break;
  619.                 case GID_LINES:
  620.                     NumLines = Code;
  621.                     break;
  622.                 case GID_SPEED:
  623.                     Speed = Code;
  624.                     break;
  625.                 }
  626.                 break;
  627.             case IDCMP_VANILLAKEY:
  628.                 Code = IntMsg->Code;
  629.                 GT_ReplyIMsg(IntMsg);
  630.                 switch ((char)Code) {
  631.                 case 'H':
  632.                 case 'h':
  633.                     CloseBlankerWindow();
  634.                     break;
  635.                 case 'Q':
  636.                 case 'q':
  637.                     Quit(0, "Normal Termination.");
  638.                 case 'B':
  639.                 case 'b':
  640.                     if (TimeUntilBlank)
  641.                         TimeUntilBlank = ThisTimeOut = 2L;
  642.                 }
  643.                 break;
  644.             default:
  645.                 GT_ReplyIMsg(IntMsg);
  646.             }
  647.  
  648.         /*
  649.          * process Commodity Messages 
  650.          */
  651.  
  652.         while (BlankerCxMsg = (CxMsg *) GetMsg(CxPort))
  653.             HandleCxMsg(Broker, BlankerCxMsg, &TimeUntilBlank, &ThisTimeOut);
  654.  
  655.         /*
  656.          * check for <CTRL>-C 
  657.          */
  658.  
  659.         if (Mask & SIGBREAKF_CTRL_C)
  660.             Quit(0, "Normal Termination.");
  661.  
  662.         /*
  663.          * Input detected, unblank if necessary 
  664.          */
  665.  
  666.         if (Mask & MASK(bsp_InputSig)) {
  667.             if (BlankFlag) {
  668.                 if (ClientPort)
  669.                     RemTool(ClientPort);
  670.  
  671.                 if (BlankerScreen) {
  672.                     SpritesOn(BlankerScreen);
  673.                     RemTool(BlankerScreen);
  674.                 } else
  675.                     Retina_DisplayOn();
  676.                 BlankFlag = 0;
  677.                 ThisTimeOut = 10L * TimeOut;
  678.             }
  679.             TimeUntilBlank = ThisTimeOut;
  680.         }
  681.         /*
  682.          * client has confirmed that it is still alive 
  683.          */
  684.  
  685.         if (Mask & MASK(bsp_ClientSig)) {
  686.             if (BlankerScreen)
  687.                 Retina_DisplayOn();
  688.             TimeUntilBlack = 10L * ClientTimeOut;
  689.             BlankFlag = 1;
  690.         }
  691.         /*
  692.          * 1/10 sec is over 
  693.          */
  694.  
  695.         if (Mask & MASK(bsp_TimerSig))
  696.             if (TimeUntilBlank) {
  697.                 TimeUntilBlank--;
  698.                 if (TimeUntilBlank == 0L) {        /*
  699.                                                  * Time Out reached,
  700.                                                  * blank * the screen 
  701.                                                  */
  702.                     struct ClientMessage ClientMessage;
  703.  
  704.                     BlankFlag = 1;
  705.                     BlankerScreen = CreateScreen(color_table);
  706.                     if (BlankerScreen)
  707.                         AddTool(BlankerScreen, DestroyScreen, 0L, NULL);
  708.                     else
  709.                         /*
  710.                          * do this if we're completely out of video
  711.                          * memory. 
  712.                          */
  713.                         Retina_DisplayOff();
  714.  
  715.                     ClientMessage.bcm_Screen = BlankerScreen;
  716.                     ClientMessage.bcm_SigMask = 1L << bsp_ClientSig;
  717.                     ClientMessage.bcm_Lines = NumLines;
  718.                     ClientMessage.bcm_Speed = Speed;
  719.  
  720.                     if (ClientPort = CreateBlankerClient(RLinesClientProcess,
  721.                                                     &ClientMessage)) {
  722.                         TimeUntilBlack = 10L * ClientTimeOut;
  723.                         /*
  724.                          * try to start Client 
  725.                          */
  726.                         AddTool(ClientPort, DeleteBlankerClient, 0L, NULL);
  727.                     }
  728.                 }
  729.             } else {
  730.                 if ((BlankerScreen) && (RetinaBase->rb_FirstScreen != BlankerScreen)) {
  731.                     Retina_ScreenToFront(BlankerScreen);
  732.                     SpritesOff(BlankerScreen);
  733.                 }
  734.                 if (TimeUntilBlack) {
  735.                     TimeUntilBlack--;
  736.                     if (TimeUntilBlack == 0L)
  737.                         Retina_DisplayOff();    /*
  738.                                                  * Client Time Out *
  739.                                                  * reached, turn entire
  740.                                                  * * screen black 
  741.                                                  */
  742.                 }
  743.             }
  744.     }
  745. }
  746.